退款 Agent 上線一段時間後,整理出一批失敗案例。
有時它引用舊版政策,有時漏掉例外條款;偶爾明明判斷可以退款,送給付款服務的參數卻不完整。最令人困擾的是,同一類案件換個問法,回答格式與結論又會改變。
於是有人提出一個看起來很合理的解法:
我們已經做了 RAG,也補了工具與流程。接下來是不是該 Fine-tuning?
這個提議並不荒謬。現在的開源工具已經讓模型訓練變得容易許多。真正危險的地方,反而是我們可能在還沒找出根因以前,就急著動了模型。
因為前面那些失敗雖然都表現成「Agent 做錯了」,根因卻可能分別位於資料、Retrieval、Context、Tool、Runtime 或模型本身。若沒有先把它們分開,Fine-tuning 很可能只是把系統的錯誤示範得更穩定。

同樣一句錯誤答案,可能來自五個不同系統層;表面症狀不能直接證明問題在模型。
這篇不會教怎麼訓練模型,而是先回答更重要的問題:
我們如何證明,問題真的已經走到必須修改模型的那一步?
先固定一個表面症狀:訂單 123 原本符合退款條件,Agent 卻拒絕了申請。
第一種情況,是送進 Context 的政策本來就是舊的。模型即使完全遵守資料,也只會得到錯誤答案。這時該修的是 Source of Truth、資料版本或 RAG 的更新流程。
第二種情況,新政策已經在知識庫裡,但 Retrieval 沒有找回真正關鍵的例外條款。模型看不到證據,問題自然不在模型權重,而在 Query、Filter、Reranking 或索引設計。
第三種情況,模型判斷正確,卻誤解了工具欄位。例如退款工具回傳的 eligible 到底表示政策符合、交易可執行,還是已經完成退款?如果 Tool Contract 沒說清楚,換成更聰明的模型也只是在猜介面的語意。
第四種情況才真正接近模型問題:新版政策、例外條款與工具結果都正確進入 Context,Prompt 也明確要求逐項核對,但模型仍在同一類案例中反覆忽略例外條件。
四種情況的畫面都可能只顯示一句「無法退款」,修法卻完全不同。
| 可觀察到的問題 | 錯誤較可能屬於 | 優先處理方式 |
|---|---|---|
| 引用舊版政策 | Source of Truth/RAG | 更新資料、版本與時效規則 |
| 正確條文存在卻沒找回 | Retrieval | 調整查詢、Filter、Reranking 或索引 |
| 工具參數或結果被誤解 | Tool Contract | 修正 Schema、描述與回傳語意 |
| 未核准就執行退款 | Runtime 規則 | 建立不可繞過的權限與核准閘門 |
| 證據與介面都正確,行為仍反覆偏離 | 模型行為 | 比較 Prompt、Few-shot、換模型與 Fine-tuning |
2026 年 6 月的 RAG 錯誤診斷研究 也採取類似方向:先區分證據缺失、證據品質與生成不忠實,再依可觀察訊號選擇不同修復方式。它的實驗不能直接等同於正式環境中的退款系統,但提醒了一件很重要的事:同樣是答案錯誤,修 Retrieval 與修生成行為從來不是同一件事。
實務上,我不會直接拿一批失敗 Trace 去訓練,而會先做一個簡單的消融實驗(Ablation Study)。做法是固定其他條件,一次只替換或排除一個環節,觀察失敗是否仍然存在。
先把同一筆失敗完整固定下來:模型版本、Prompt、取回的 Context、Tool Schema、工具結果與預期答案都不能偷偷改變。接著一次只替換一個環節。
如果換成正確 Context 後就恢復正常,問題屬於資料或 Retrieval。如果加上兩三個範例後就穩定通過,Few-shot 可能已經足夠。如果只有換成較強模型才改善,團隊還要比較模型升級與自行維護訓練版本的成本。
只有在前面條件都固定後,錯誤仍能在一組代表性案例中穩定出現,我們才得到一個可信的模型行為缺口。

消融實驗固定其他條件,一次替換一個環節;第一個讓錯誤消失的位置,就是優先修復層。
這個方法的價值,是把「我覺得模型不夠懂」變成可以反駁的工程假設。每一次替換都在問:拿掉這一層的不確定性後,失敗還在不在?
完成消融實驗後,我們才有資格討論修法。Prompt、RAG、Workflow 與 Fine-tuning 並不是一條由低到高的升級路線,而是在改變系統的不同部分。
如果明天退款政策改版,我們希望能立即替換來源、標記生效時間並追溯引用,而不是重新訓練後猜測模型記住多少。若高額退款需要主管核准,我們希望付款工具在缺少核准收據時直接拒絕,而不是相信模型通常會守規則。
真正適合訓練的,通常是能用一致範例描述的行為,例如固定輸出格式、穩定分類、品牌語氣,或是在工具介面已經清楚的前提下選擇正確工具。

Prompt、RAG、Tool、Runtime 與 Fine-tuning 並非成熟度階梯,而是各自承擔不同責任。
這裡的關鍵不是 Fine-tuning 能不能改善某個分數,而是:這個責任原本就應該放在模型裡嗎?
RAG 與 Fine-tuning 並不是二選一。RAG 負責把最新且可追溯的證據帶進來;Fine-tuning 則可能讓模型更穩定地使用這些證據。
原始 RAFT 研究 的重點,不是把領域文件全部記進模型,而是在開卷情境中訓練模型辨認有用文件、忽略干擾內容,並根據證據作答。
因此,如果文件沒有被找回,先修 Retrieval;如果文件已經找回,模型卻持續被干擾資料帶偏,才可能評估像 RAFT 這類結合 Retrieval 與訓練的方法。
這個差異會改變整個系統的更新責任:知識仍然留在外部,訓練的是使用知識的行為。
定位到模型行為,不代表 Fine-tuning 就一定划算。正式投入前,我會再檢查三件事。
如果只能挑出幾筆感覺不好的回答,卻無法定義失敗條件,應先回到 Evaluation 與 Trace。訓練前需要明確的同類錯誤案例,以及一批未參與訓練的獨立測試資料;否則無法證明改善,也看不見其他能力是否回退。
訓練資料不能只收集失敗回答,還要能展示相同條件下什麼才是正確行為,並涵蓋正常案例、例外、反例與拒答情境。如果團隊無法對範例達成一致,訓練只會把原本的歧義搬進權重。
成本不只有一次訓練所需的 GPU。資料清理、專家標註、Evaluation、Serving、監控、基礎模型升級與回滾,都會伴隨客製模型存在。若一個 Prompt 範例、較合適的基礎模型或更清楚的 Tool Contract 就能修好問題,訓練未必是合理投資。
大廠的模型最佳化流程普遍把 Evaluation、Prompt 與代表正式流量的資料放在訓練之前;LlamaFactory 與 ms-swift 等開源專案,則讓模型訓練的操作門檻持續下降。兩者放在一起看,反而得到一個值得注意的結論:當訓練變得容易,錯誤歸因與資料品質才會成為真正的門檻。
團隊最後決定針對「看見完整例外條款,仍錯誤拒絕退款」建立一組案例。
這次他們沒有把所有失敗 Trace 混成訓練集,而是先排除舊政策、漏檢索、工具語意與權限問題,只留下真正屬於模型判讀的同類錯誤案例。接著保留一批模型從未看過的案件作為測試集。
比較的對象也不只兩個:
所有版本都使用相同的測試案例、知識快照與 Tool Contract,再比較退款判斷、證據使用、工具參數、延遲、單次成本,以及原本能力是否回退。
這才是公平的升級實驗。否則 Fine-tuning 一方拿到幾百個精心整理的範例,Baseline 卻只使用一段模糊 Prompt,最後得到的不是技術勝負,而是投入程度不同。

只有固定測試集、知識快照與 Tool Contract,才能比較各種方案真正帶來的邊際增益。
即使 Fine-tuning 勝出,結論也不應寫成「模型升級成功」,而應更具體:它改善了哪一類錯誤、代價是多少、是否影響其他能力,以及政策改版後哪些部分仍必須由 RAG 與 Runtime 負責。
走到這裡,我們終於可以回答開頭的問題。
Agent 做不好,不代表下一步就是 Fine-tuning。只有當正確資料、Context、Tool 與控制邊界都已經存在,模型仍對同一類輸入反覆產生可描述、可量測的行為差距,Fine-tuning 才從一個流行選項變成合理的工程假設。
真正的分界不在於團隊會不會訓練,而在於能不能完成這句話:
在其他系統條件都固定後,我們希望模型對這一類輸入,更穩定地做出這一種行為。
如果這句話說不清楚,先不要動權重。
因為最昂貴的錯誤,不是 Fine-tuning 沒有效果;而是把資料過期、介面模糊或制度缺口寫進模型,最後得到一個更有自信、也更難追查的錯誤版本。

工程師:「我準備了十萬筆資料,這次一定能修好 Agent。」AI:「那份已經過期的退款政策,也會一起變得更熟練嗎?」